package titt.server.service.invoker;

import titt.head.HTTPHead;
import titt.io.IOFactory;
import titt.io.socket.TITTSocket;
import titt.server.os.ObjectServer;
import titt.server.service.PipedSocket;
import titt.service.proxy.TITTRequester;
import titt.type.TypedObject;

public class TITTInternalInvoker {

	private final String serviceID;
	private final ObjectServer os;

	private final TITTRequester tr = new TITTRequester();

	public TITTInternalInvoker(String serviceID, ObjectServer os) {
		this.os = os;
		this.serviceID = serviceID;
	}

	private void close(TITTSocket... tss) {
		for(TITTSocket ts : tss)
			try {
				ts.close();
			}
			catch(Exception e) {}
	}
	
	public <T> T call(String methodName, Object... args) throws Exception {
		PipedSocket ps = new PipedSocket();

		final TITTSocket 	sink = IOFactory.createTITTSocket(ps), 
							source = IOFactory.createTITTSocket(ps.getPipedSocket());

		try {

			tr.sendRequest(source, methodName, args);

			HTTPHead head = sink.getHeadReader().readHead();

			os.getServerInternal().request(serviceID, sink, head);			
			
			TypedObject ret = tr.readResponse(source);
			
			close(sink, source);

			return ret.getObject();

		}
		catch(Exception e) {
			close(sink, source);

			throw e;
		}

	}

}
